package com.bsoft.gol.hcs.specialist.dao;

import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import com.bsoft.gol.hcs.enumcase.FollowTypeEnum;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import com.bsoft.gol.hcs.specialist.bean.request.GroupChronicRecordQo;
import com.bsoft.gol.hcs.specialist.bean.response.FactorData;
import com.bsoft.gol.hcs.specialist.bean.response.OutPatientInfoListResponse;
import com.bsoft.gol.hcs.specialist.entity.FusAnswerOutpatientInfo;
import com.bsoft.gol.hcs.utils.CommonUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author tongtp
 * @version v0.1
 * @className FusAnswerOutpatientInfoDAO
 * @description
 * @create 2020-07-31 15:08
 **/
public abstract class FusAnswerOutpatientInfoDAO extends HibernateSupportDelegateDAO<FusAnswerOutpatientInfo> {

	/**
	 * @param reportId
	 * @throws
	 * @description: 根据表单答案唯一记录id查询
	 * @return: specialist.entity.FusAnswerOperativeInfo
	 * @author: tongtp
	 * @date: 2020/8/4 17:57
	 */
	@DAOMethod(sql = " from FusAnswerOutpatientInfo where reportId = :reportId")
	public abstract FusAnswerOutpatientInfo getByReportId(@DAOParam("reportId") String reportId);

	/**
	 *
	 * 根据病人id和病种id获取门诊信息
	 * @param qo
	 * @return
	 */
	public List<OutPatientInfoListResponse> queryAnswerOutPatientInfoList(GroupChronicRecordQo qo) {
		HibernateStatelessResultAction<List<OutPatientInfoListResponse>> action = new AbstractHibernateStatelessResultAction<List<OutPatientInfoListResponse>>() {
			@Override
			public void execute(StatelessSession ss) throws Exception {
				StringBuilder sqlBuilder = new StringBuilder();
				sqlBuilder.append("SELECT fus_answer_outpatient_info_id as outPatientInfoId,visit_time as visitTime from fus_answer_outpatient_info WHERE patient_id =:patientId and disease_type_id =:diseaseTypeId ");
				sqlBuilder.append(" and create_time >=:beginTime and create_time <=:endTime order by create_time ");
				Query query = ss.createSQLQuery(sqlBuilder.toString());
				query.setParameter("patientId", qo.getPatientId());
				query.setParameter("diseaseTypeId", qo.getDiseaseTypeId());
				if (CommonUtils.isNotEmpty(qo.getBeginTime())){
					query.setParameter("beginTime", qo.getBeginTime()+" 00:00:00");
				}
				if (CommonUtils.isNotEmpty(qo.getBeginTime())){
					query.setParameter("endTime", qo.getEndTime()+" 23:59:59");
				}
				query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
				List<Map> list = query.list();
				List<OutPatientInfoListResponse> voList = new ArrayList<>();
				if (CommonUtils.isNotEmpty(list)) {
					for (Map map : list) {
						voList.add(ConversionUtils.convert(map, OutPatientInfoListResponse.class));
					}
				} else {
					voList = new ArrayList<>();
				}
				setResult(voList);
			}
		};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}

	/**
	 * 根据用户和病种查询ReportId
	 *
	 * @param diseaseTypeId
	 * @param patientId
	 * @param patientMedicalCardType
	 * @param patientMedicalCardNumber
	 * @param cardType
	 * @param cardNumber
	 * @return java.util.List<java.lang.String>
	 * @throws
	 * @author tongtp
	 * @date 2021/12/29 13:41
	 */
	public List<String> queryReportId(Long diseaseTypeId, String patientId,
									  Integer patientMedicalCardType, String patientMedicalCardNumber,
									  String cardType, String cardNumber) {
		HibernateStatelessResultAction<List<String>> action =
				new AbstractHibernateStatelessResultAction<List<String>>() {
					@Override
					public void execute(StatelessSession ss) throws Exception {
						StringBuilder sqlBuilder = new StringBuilder();
						sqlBuilder.append("select report_id from fus_answer_outpatient_info" +
								"  where disease_type_id = :diseaseTypeId ");
						sqlBuilder.append(" and ( ");
						if (CommonUtils.isNotNull(patientId)) {
							sqlBuilder.append(" patient_id = :patientId ");
						}
						if (CommonUtils.isNotNull(patientMedicalCardType) && CommonUtils.isNotNull(patientMedicalCardNumber)) {
							sqlBuilder.append("  or (patient_medical_card_type = :patientMedicalCardType and" +
									" patient_medical_card_number = :patientMedicalCardNumber) ");
						}
						if (CommonUtils.isNotNull(cardType) && CommonUtils.isNotNull(cardNumber)) {
							sqlBuilder.append("  or (card_type = :cardType and" +
									" card_number = :cardNumber) ");
						}
						sqlBuilder.append(" ) ");
						Query query = ss.createSQLQuery(sqlBuilder.toString());
						query.setParameter("diseaseTypeId", diseaseTypeId);
						if (CommonUtils.isNotNull(patientId)) {
							query.setParameter("patientId", patientId);
						}
						if (CommonUtils.isNotNull(patientMedicalCardType) && CommonUtils.isNotNull(patientMedicalCardNumber)) {
							query.setParameter("patientMedicalCardType", patientMedicalCardType);
							query.setParameter("patientMedicalCardNumber", patientMedicalCardNumber);
						}
						if (CommonUtils.isNotNull(cardType) && CommonUtils.isNotNull(cardNumber)) {
							query.setParameter("cardType", cardType);
							query.setParameter("cardNumber", cardNumber);
						}
						List list = query.list();
						List<String> voList;
						if (CommonUtils.isNotEmpty(list)) {
							voList = list;
						} else {
							voList = new ArrayList<>();
						}
						setResult(voList);
					}
				};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}

	/**
	 * @description: 根据诊断编码、诊断时间、病人id集合查询诊断记录集合
	 * @param: factorIdList 诊断编码集合
	 * @param: diagnosisTime
	 * @param: diagnosisServiceType 业务诊断类型：1入院诊断、2出院诊断、3门诊诊断、5其他诊断
	 * @param: patientIdList
	 * @return: java.util.List<specialist.bean.response.FactorData>
	 */
	public List<FactorData> executeFactorForOutpatient(List<String> factorIdList, Date startTime, Date endTime, String diagnosisServiceType, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
		HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
			@Override
			public void execute(StatelessSession ss) throws Exception {
				StringBuilder sqlBuilder = new StringBuilder();
				sqlBuilder.append("select patientId,organizationId,visitRecordId,doctorId ,doctorName,visitTime,'2' as dataSource from (");
				sqlBuilder.append("SELECT patient_id as patientId,organization_id organizationId,user_info_id visitRecordId, ");
				sqlBuilder.append(" doctor_id doctorId,doctor_name doctorName,visit_time visitTime");
				sqlBuilder.append("  FROM `fus_answer_outpatient_info`  ");
				sqlBuilder.append(" WHERE doctor_id in(:doctorIdList)  ");
				if (null != startTime) {
					sqlBuilder.append("  and  visit_time>:startTime ");
				}
				if (null != endTime) {
					sqlBuilder.append("  and  visit_time<:endTime ");
				}
				if (CommonUtils.isNotEmpty(patientIdList)) {
					sqlBuilder.append(" and patient_id in(:patientIdList)");
				}
                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.visit_record_id = m.visitRecordId WHERE f.id IS NULL  ");
                }
				Query query = ss.createSQLQuery(sqlBuilder.toString());
				query.setParameterList("doctorIdList", factorIdList);
				if (null != startTime) {
					query.setParameter("startTime", startTime);
				}
				if (null != endTime) {
					query.setParameter("endTime", endTime);
				}
				if (CommonUtils.isNotEmpty(patientIdList)) {
					query.setParameterList("patientIdList", patientIdList);
				}
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
				query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
				List<Map> list = query.list();
				List<FactorData> voList = new ArrayList<>();
				if (CommonUtils.isNotEmpty(list)) {
					for (Map map : list) {
						voList.add(ConversionUtils.convert(map, FactorData.class));
					}
				} else {
					voList = new ArrayList<>();
				}
				setResult(voList);
			}
		};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}


	public List<FactorData> executeFactorForOutpatientStatus(List<String> deptIdList, Date endTime, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
		HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
			@Override
			public void execute(StatelessSession ss) throws Exception {
				StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,visitRecordId,dataSource from (");
				sqlBuilder.append("SELECT patient_id patientId,report_id visitRecordId,'2' as dataSource FROM ");
				sqlBuilder.append(" (SELECT patient_id ,MAX(visit_time) visit_time, report_id FROM `fus_answer_outpatient_info` ");
				sqlBuilder.append(" WHERE 1=1 ");
				if (CommonUtils.isNotEmpty(deptIdList)) {
					sqlBuilder.append(" and department_id in (:deptIdList) ");
				}
				sqlBuilder.append(" GROUP BY patient_id) a");
				sqlBuilder.append(" WHERE visit_time<:endTime");
				if (CommonUtils.isNotEmpty(patientIdList)) {
					sqlBuilder.append(" and patient_id in(:patientIdList)");
				}
				sqlBuilder.append(") AS  m ");
				//循环执行机制 0 不执行 1 执行
				if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
					sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f" +
							".route_detail_id = :routeDetailId AND f.visit_record_id = m.visitRecordId WHERE f.id IS " +
							"NULL  ");
				}
				Query query = ss.createSQLQuery(sqlBuilder.toString());
				query.setParameter("endTime", endTime);
				if (CommonUtils.isNotEmpty(deptIdList)) {
					query.setParameterList("deptIdList", deptIdList);
				}
				if (CommonUtils.isNotEmpty(patientIdList)) {
					query.setParameterList("patientIdList", patientIdList);
				}
				if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
					query.setParameter("routeDetailId", routeDetailId);
				}
				query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
				List<Map> list = query.list();
				List<FactorData> voList = new ArrayList<>();
				if (CommonUtils.isNotEmpty(list)) {
					for (Map map : list) {
						voList.add(ConversionUtils.convert(map, FactorData.class));
					}
				} else {
					voList = new ArrayList<>();
				}
				setResult(voList);
			}
		};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}

	public List<FactorData> executeFactorForOutpatientStatus(List<String> deptIdList, Date startTime, Date endTime, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
		HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
			@Override
			public void execute(StatelessSession ss) throws Exception {
				StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,visitRecordId,dataSource from (");
				sqlBuilder.append("SELECT patient_id patientId ,report_id visitRecordId,'2' as dataSource FROM `fus_answer_outpatient_info`");
				sqlBuilder.append(" WHERE 1=1 ");
				if (CommonUtils.isNotEmpty(deptIdList)) {
					sqlBuilder.append(" and department_id in (:deptIdList) ");
				}
				if (CommonUtils.isNotEmpty(startTime)) {
					sqlBuilder.append(" and visit_time>:startTime");
				}
				if (CommonUtils.isNotEmpty(endTime)) {
					sqlBuilder.append(" and visit_time<:endTime");
				}
				if (CommonUtils.isNotEmpty(patientIdList)) {
					sqlBuilder.append(" and patient_id in(:patientIdList)");
				}
				sqlBuilder.append(") AS  m ");
				//循环执行机制 0 不执行 1 执行
				if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
					sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f" +
							".route_detail_id = :routeDetailId AND f.visit_record_id = m.visitRecordId WHERE f.id IS" +
							" " +
							"NULL  ");
				}
				Query query = ss.createSQLQuery(sqlBuilder.toString());
				if (CommonUtils.isNotEmpty(startTime)) {
					query.setParameter("startTime", startTime);
				}
				if (CommonUtils.isNotEmpty(endTime)) {
					query.setParameter("endTime", endTime);
				}
				if (CommonUtils.isNotEmpty(deptIdList)) {
					query.setParameterList("deptIdList", deptIdList);
				}
				if (CommonUtils.isNotEmpty(patientIdList)) {
					query.setParameterList("patientIdList", patientIdList);
				}
				if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
					query.setParameter("routeDetailId", routeDetailId);
				}
				query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
				List<Map> list = query.list();
				List<FactorData> voList = new ArrayList<>();
				if (CommonUtils.isNotEmpty(list)) {
					for (Map map : list) {
						voList.add(ConversionUtils.convert(map, FactorData.class));
					}
				} else {
					voList = new ArrayList<>();
				}
				setResult(voList);
			}
		};
		HibernateSessionTemplate.instance().execute(action);
		return action.getResult();
	}
}
